

MessageBuilder = function(registered) {
    this.registered = registered;
};

MessageBuilder.prototype.serialize = function(message) {
    return message.as_json();
};

MessageBuilder.prototype.build = function(packet) {
    for(var i in this.registered) {
        var candidate = this.registered[i];
        if(candidate.prototype.signature == packet.signature) {
            return candidate.prototype.build(packet);
        }
    }
};

Channel = function(builder) {
	this.builder = builder;
};

Channel.prototype.connect = function(location) {
	var channel = this;
	this.socket = new WebSocket(location);
	this.socket.onopen = function() {
		logging.debug("WS socket opened");
		// MARK buffer
	};
	this.socket.onmessage = function(string){
		logging.debug("WS message received: " + string.data);
		var packet = JSON.parse(string.data);
		channel.received(packet);
	};
};

Channel.prototype.received = function(packet) {
	var message = this.builder.build(packet);
	message.perform();
};

Channel.prototype.send = function(packet) {
	var string = JSON.stringify(packet);
    logging.debug("WS message sending: " + string);
    // MARK buffer
    this.socket.send(string);
};

Channel.prototype.close = function() {
    this.socket.onclose = function() {
    	// disable onclose handler first
    }; 
	this.socket.close();
};


Message = function() {
	// no members
};

Message.prototype.as_json = function() {
    return {signature: this.signature};
};

Message.prototype.send = function() {
	CHANNEL.send(this.as_json()); // TODO
};

ClientMessage = function() {
    Message.call(this);
};

ClientMessage.prototype = new Message;

ServerMessage = function() {
    Message.call(this);
};

ServerMessage.prototype = new Message;
ServerMessage.prototype.perform = function() {
	// MARK noop default implementation
};
ServerMessage.prototype.build = function(payload) {
	// MARK noop default construction
};


